﻿//------------------------------------------------------------------------------
// <copyright file="FallingThings.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

// This module contains code to do display falling shapes, and do
// hit testing against a set of segments provided by the Kinect NUI, and
// have shapes react accordingly.

namespace ShapeGame
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using Microsoft.Kinect;
    using ShapeGame.Utils;
    using System.Diagnostics;

    // FallingThings is the main class to draw and maintain positions of falling shapes.  It also does hit testing
    // and appropriate bouncing.
    public class Theremin
    {
        private readonly Random rnd = new Random();
        private readonly int intraFrames = 1;
        private Rect sceneRect;
        private double targetFrameRate = 60;
        private int frameCount;
        private System.Windows.Media.Color baseColor = System.Windows.Media.Color.FromRgb(0, 0, 0);
        private DateTime gameStartTime;
        private ThereminSound myThereminSound;
        public double rightVolumeX, rightVolumeY;
        public double leftPitchX, leftPitchY;
        public double leftHandX, leftHandY, leftHandZ;
        public double rightHandX, rightHandY, rightHandZ;
        public double volume, pitch;
        public bool highPassFilter, lowPassFilter;

        public Theremin(double framerate, int intraFrames)
        {
            this.intraFrames = intraFrames;
            this.targetFrameRate = framerate * intraFrames;
            this.sceneRect.X = this.sceneRect.Y = 0;
            this.sceneRect.Width = this.sceneRect.Height = 100;

            rightVolumeX = 200;
            rightVolumeY = 350;
            leftPitchX = 400;
            leftPitchY = 350;

            volume = 0;
            pitch = 0;

            highPassFilter = false;
            lowPassFilter = false;

            myThereminSound = new ThereminSound();
        }

        public static Label MakeSimpleLabel(string text, Rect bounds, System.Windows.Media.Brush brush)
        {
            Label label = new Label { Content = text };
            if (bounds.Width != 0)
            {
                label.SetValue(Canvas.LeftProperty, bounds.Left);
                label.SetValue(Canvas.TopProperty, bounds.Top);
                label.Width = bounds.Width;
                label.Height = bounds.Height;
            }

            label.Foreground = brush;
            label.FontFamily = new System.Windows.Media.FontFamily("Arial");
            label.FontWeight = FontWeight.FromOpenTypeWeight(600);
            label.FontStyle = FontStyles.Normal;
            label.HorizontalAlignment = HorizontalAlignment.Center;
            label.VerticalAlignment = VerticalAlignment.Center;
            return label;
        }

        public void SetFramerate(double actualFramerate)
        {
            this.targetFrameRate = actualFramerate * this.intraFrames;
        }

        public void SetBoundaries(Rect r)
        {
            this.sceneRect = r;
        }

        public void Reset()
        {
            this.gameStartTime = DateTime.Now;
        }

        public void AdvanceFrame()
        {
            
        }

        public void DrawFrame(UIElementCollection children)
        {
            this.frameCount++;

            // Volume loop for left hand
            Line volumePoint = new Line();
            volumePoint.Stroke = System.Windows.Media.Brushes.White;
            volumePoint.X1 = rightVolumeX;
            volumePoint.X2 = rightVolumeX;
            volumePoint.Y1 = rightVolumeY;
            volumePoint.Y2 = rightVolumeY-100;
            children.Add(volumePoint);

            // Pitch antenna for right hand
            Line pitchPoint = new Line();
            pitchPoint.Stroke = System.Windows.Media.Brushes.White;
            pitchPoint.X1 = leftPitchX;
            pitchPoint.X2 = leftPitchX+30;
            pitchPoint.Y1 = leftPitchY;
            pitchPoint.Y2 = leftPitchY;
            children.Add(pitchPoint);

        }

        private static double SquaredDistance(double x1, double y1, double x2, double y2)
        {
            return ((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1));
        }

        public void playSine()
        {
            myThereminSound.StartStopSineWave();
        }

        public void playSquare()
        {
            myThereminSound.StartStopSquareWave();
        }

        #region Hand Processing

        public void calculateVolume(Player player)
        {
            double distance;

            if (player != null)
            {
                rightHandY = player.getRightHandY();
            }

            distance = rightHandY;
            this.volume = Math.Abs(distance);
            //Debug.Print("Volume: " + volume);
            myThereminSound.setVolume((float)volume);
        }

        public void calculatePitch(Player player)
        {
            double distance;

            if (player != null)
            {
                leftHandY = player.getLeftHandY();
            }

            distance = Math.Abs(leftHandY);
            this.pitch = getPitch(distance);

            if (highPassFilter == true)
            {
                if (this.pitch < 329)
                {
                    this.pitch = 329;
                }
            }
            else if (lowPassFilter == true)
            {
                if (this.pitch > 440)
                {
                    this.pitch = 440;
                }
            }

            //Debug.Print("Pitch: " + pitch);
            myThereminSound.setPitch((float)pitch);
        }

        public double getPitch(double distance)
        {
            double pitch = 0;

            if (distance > 0 && distance < .0625) {
                pitch = 523;
            }
            else if (distance > .0625 && distance < .125)
            {
                pitch = 493;
            }
            else if (distance > .125 && distance < .1875)
            {
                pitch = 440;
            }
            else if (distance > .1875 && distance < .25)
            {
                pitch = 349;
            }
            else if (distance > .1875 && distance < .3125)
            {
                pitch = 329;
            }
            else if (distance > .3125 && distance < .375)
            {
                pitch = 293;
            }
            else if (distance > .375 && distance < .5)
            {
                pitch = 261;
            }
            else
            {
                pitch = 0;
            }

            return pitch;

        }

        #endregion Hand Processing
    }
}
